home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Application Source ƒ / 68k Internet Config ƒ / C Source ƒ / IC Windows.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-04  |  22.2 KB  |  955 lines  |  [TEXT/SPM ]

  1. /*
  2.     IC Windows.c
  3.     
  4. */
  5.  
  6. #include <QuickDraw.h>
  7. #include <ToolUtils.h>
  8.  
  9. #include "IC Globals.h"
  10. #include "IC Window Globals.h"
  11. #include "IC Misc Subs.h"
  12. #include "IC Types.h"
  13. #include "IC API.h"
  14. #include "IC Dialogs.h"
  15. #include "IC Text.h"
  16. #include "IC Globals.h"
  17. #include "IC Keys.h"
  18. #include "IC Text Whats.h"
  19. #include "IC Popup Whats.h"
  20. #include "IC Font Whats.h"
  21. #include "IC FSSpec Whats.h"
  22. #include "IC File Map What.h"
  23. #include "IC Helper What.h"
  24. #include "IC Button What.h"
  25. #include "IC Document.h"
  26. #include "IC Windows.h"
  27. #include "IC Subs.h"
  28. #include "IC CheckBox What.h"
  29. #include "IC Events.h"
  30.  
  31. #include "SpinLib.h"
  32.  
  33. /*
  34.     Force the update of the about window.
  35. */
  36. void InvalidateAbout(void){
  37.     Rect r;
  38.     WindowPeek peek=(WindowPeek)(WindowInfo[WT_About].window);
  39.     GrafPtr cur;
  40.     
  41.     if (peek->visible){
  42.         // get the rect of our little item
  43.         GetPort(&cur);
  44.         SetPort(WindowInfo[WT_About].window);
  45.         
  46.         GetDItemRect(WindowInfo[WT_About].window,8,&r);
  47.         
  48.         // invalidate it so we get a redraw.
  49.         InvalRect(&r);
  50.         
  51.         SetPort(cur);
  52.     }
  53. }
  54.  
  55. OSErr CallWhatOpen(WindowType wt,short item,WindowPlainUPP open){
  56.     return CallWindowPlainProc(open,wt,item);
  57. }
  58.  
  59. OSErr CallWhatClose(WindowType wt,short item,WindowPlainUPP close){
  60.     return CallWindowPlainProc(close,wt,item);
  61. }
  62.  
  63. OSErr CallWhatFlush(WindowType wt,short item,WindowPlainUPP flush){
  64.     return CallWindowPlainProc(flush,wt,item);
  65. }
  66.  
  67. OSErr CallWhatClick(WindowType wt,short item,EventRecord* er,WindowEventUPP click){
  68.     return CallWindowEventProc(click,wt,item,er);
  69. }
  70.  
  71. OSErr CallWhatKey(WindowType wt,short item,EventRecord* er,WindowEventUPP key){
  72.     return CallWindowEventProc(key,wt,item,er);
  73. }
  74.  
  75. OSErr CallWhatActivate(WindowType wt,short item,Boolean activate,WindowBooleanUPP actproc){
  76.     return CallWindowBooleanProc(actproc,wt,item,activate);
  77. }
  78.  
  79. OSErr CallWhatIdle(WindowType wt,short item,WindowPlainUPP idleproc){
  80.     return CallWindowPlainProc(idleproc,wt,item);
  81. }
  82.  
  83. OSErr CallWhatCursor(WindowType wt,short item,Point pt,short curs,WindowCursorUPP cursproc){
  84.     return CallWindowCursorProc(cursproc,wt,item,pt,curs);
  85. }
  86.  
  87. short TypeToWhat(OSType typ){
  88.     short i;
  89.     
  90.     for (i=1;i<=whats_max;i++){
  91.         if (WhatInfo[i].typ==typ){
  92.             return i;
  93.         }
  94.     }
  95.     
  96.     return 1;
  97. }
  98.  
  99. OSType GetWhatType(WindowType wt,short item){
  100.     WhatRecordPtr wrp;
  101.     
  102.     if (item>item_max)
  103.         return (OSType)0;
  104.     
  105.     wrp=WindowInfo[wt].items[item];
  106.     if (wrp==(WhatRecordPtr)0)
  107.         return 'NULL';
  108.     
  109.     return wrp->typ;
  110. }
  111.  
  112. WindowPtr GetWindowPtr(WindowType wt){
  113.     return WindowInfo[wt].window;
  114. }
  115.  
  116. Boolean OurWindow(WindowPtr wp){
  117.     return GetWindowType(wp)!=WT_None;
  118. }
  119.  
  120. OSErr WhatIdleText(WindowType wt,short item,short* cursor){
  121.     Rect r;
  122.     Point pt;
  123.     
  124.     GetDItemRect(WindowInfo[wt].window,item,&r);
  125.     GetMouse(&pt);
  126.     if (PtInRect(pt,&r))
  127.         *cursor=iBeamCursor;
  128.     return noErr;
  129. }
  130.  
  131. void DoWindowIdle(WindowPtr window){
  132.     short i,selected_item,cursorid;
  133.     WhatRecordPtr what;
  134.     WindowType wt;
  135.     Rect r;Point pt;
  136.     WindowCursorUPP cursor;
  137.     Boolean cursor_set;
  138.     
  139.     SetPort(window);
  140.     wt=GetWindowType(window);
  141.     selected_item=GetSelectedItem(wt);
  142.     if (selected_item>0)
  143.         TextIdle(WindowInfo[wt].items[selected_item]->data);
  144.     
  145.     if ((window==FrontWindow())&&(InForeground())){
  146.         GetMouse(&pt);
  147.         cursor_set=false;
  148.         
  149.         for (i=1;i<=item_max;i++){
  150.             what=WindowInfo[wt].items[i];
  151.             if (what!=(WhatRecordPtr)0){
  152.                 GetDItemRect(window,i,&r);
  153.                 if (PtInRect(pt,&r)){
  154.                     cursor_set=true;
  155.                     cursorid=WhatInfo[TypeToWhat(what->typ)].cursorid;
  156.                     cursor=(WindowCursorUPP)WhatInfo[TypeToWhat(what->typ)].cursor;
  157.                     
  158.                     if (cursor==(WindowCursorUPP)0){
  159.                         if (cursorid==0)
  160.                             InitCursor();
  161.                         else {
  162.                             CursHandle curs;
  163.                             
  164.                             curs=GetCursor(cursorid);
  165.                             if (curs!=(CursHandle)0)
  166.                                 SetCursor(*curs);
  167.                         }
  168.                     } else
  169.                         CallWhatCursor(wt,i,pt,cursorid,cursor);
  170.                 }
  171.             }
  172.         }
  173.         
  174.         if (!cursor_set)
  175.             InitCursor();
  176.     }
  177. }
  178.  
  179. void WindowDoKey(WindowPtr window,EventRecord* er){
  180.     short wt=GetWindowType(window);
  181.     short selected_item=WindowInfo[wt].selected_item;
  182.     WindowEventUPP key;
  183.     
  184.     if (selected_item>0){
  185.         key=(WindowEventUPP)WhatInfo[TypeToWhat(GetWhatType(wt,selected_item))].key;
  186.         if (key!=(WindowEventUPP)0){
  187.             SetPort(window);
  188.             DisplayError(acDoThis,CallWhatKey(wt,selected_item,er,key));
  189.         }
  190.     }
  191. }
  192.  
  193. void WindowActivateDeactivate(WindowPtr window,Boolean activate){
  194.     WindowType wt=GetWindowType(window);
  195.     short item,i;
  196.     WindowBooleanUPP actproc;
  197.     WhatRecordPtr what;
  198.     OSErr err;
  199.     
  200.     if (wt!=WT_None){
  201.         SetPort(window);
  202.         item=GetSelectedItem(wt);
  203.         if (item>0)
  204.             TextActivate(WindowInfo[wt].items[item]->data,activate);
  205.         for (i=1;i<=item_max;i++){
  206.             what=WindowInfo[wt].items[i];
  207.             if (what!=(WhatRecordPtr)0){
  208.                 actproc=(WindowBooleanUPP)WhatInfo[TypeToWhat(what->typ)].activate;
  209.                 if (actproc!=(WindowBooleanUPP)0){
  210.                     err=CallWhatActivate(wt,i,activate,actproc);
  211.                     if ((err!=noErr)&&(err!=userCanceledErr))
  212.                         SysBeep(1);
  213.                 }
  214.             }
  215.         }
  216.     }
  217. }
  218.  
  219. ICError LaunchSomeSillyURL(StringPtr url){
  220.     long start,fin;
  221.     Str255 hint="\p";
  222.     
  223.     start=url[0]/2;
  224.     fin=start;
  225.     
  226.     return ICLaunchURL(GetInstance(),hint,(Ptr)&(url[1]),url[0],&start,&fin);
  227. }
  228.  
  229. void DoAboutClick(WindowPtr window,short item){
  230.     short a;
  231.     Str255 s;
  232.     
  233.     if (TrackItems(window,item,0,0)){
  234.         if (item==6){
  235.             a=NoteAlert(167,gCancelModalFilter);
  236.             if (a==1)
  237.                 item=7;
  238.             else if (a==2)
  239.                 item=0;
  240.         }
  241.         
  242.         if (item==8) // no url for the latest item
  243.             item=0;
  244.         
  245.         if (item!=0){
  246.             GetIndString(s,129,item);
  247.             DisplayError(acDoThis,LaunchSomeSillyURL(s));
  248.         }
  249.     }
  250. }
  251.  
  252. void WindowItemWhere(WindowPtr window,EventRecord* er,short item){
  253.     WindowEventUPP click;
  254.     WindowType wt=GetWindowType(window);
  255.     
  256.     if (wt==WT_About)
  257.         DoAboutClick(window,item);
  258.     else {
  259.         click=(WindowEventUPP)WhatInfo[TypeToWhat(GetWhatType(wt,item))].click;
  260.         if (click!=(WindowEventUPP)0){
  261.             SetPort(window);
  262.             DisplayError(acDoThis,CallWhatClick(wt,item,er,click));
  263.         }
  264.     }
  265. }
  266.  
  267. Boolean WindowEarlyHandleEvent(WindowPtr window,EventRecord* er){
  268.     return false;
  269. }
  270.  
  271. void WindowTab(WindowPtr window,Boolean shift){
  272.     short orgitem,rorgitem,i,dirn,selitem=-1;
  273.     OSType t;
  274.     WindowType wt=GetWindowType(window);
  275.     short ash=(shift)?2:0;
  276.     
  277.     orgitem=rorgitem=GetSelectedItem(wt);
  278.     if (orgitem<=0){
  279.         if (shift)
  280.             orgitem=1;
  281.         else
  282.             orgitem=item_max;
  283.     }
  284.     dirn=item_max-ash;
  285.     i=orgitem;
  286.     
  287.     do {
  288.         i=(i+dirn)%item_max +1;
  289.         t=GetWhatType(wt,i);
  290.         if (t=='TEXT'){
  291.             selitem=i;
  292.             break;
  293.         }
  294.     } while (i!=orgitem);
  295.     if (selitem>0)
  296.         SelectTextItem(wt,selitem);
  297. }
  298.  
  299. Boolean WindowEarlyHandleKey(WindowPtr window,EventRecord* er){
  300.     Boolean b=false;
  301.     char ch;
  302.     WindowType wt=GetWindowType(window);
  303.     
  304.     if (!WindowInfo[wt].window_key_needs_tabs){
  305.         ch=er->message&0xff;
  306.         if (ch==tabChar){
  307.             WindowTab(window,((er->modifiers&shiftKey)!=0));
  308.             b=true;
  309.         }
  310.     }
  311.     return b;
  312. }
  313.  
  314. OSErr FlushWindowType(WindowPtr wp,WindowType wt){
  315.     short i;
  316.     OSErr first_err=noErr,err;
  317.     WindowPlainUPP flush;
  318.     WhatRecordPtr what;
  319.     Rect portrect;
  320.     
  321.     SetPort(wp);
  322.     GetWindowRect(wp,&portrect);
  323.     WindowInfo[wt].position=topLeft(portrect);
  324.     for (i=1;i<=item_max;i++){
  325.         what=WindowInfo[wt].items[i];
  326.         if (what!=(WhatRecordPtr)0){
  327.             flush=(WindowPlainUPP)WhatInfo[TypeToWhat(what->typ)].flush;
  328.             if (flush!=(WindowPlainUPP)0){
  329.                 err=CallWhatFlush(wt,i,flush);
  330.                 if (first_err==noErr)
  331.                     first_err=err;
  332.             }
  333.         }
  334.     }
  335.     
  336.     return first_err;
  337. }
  338.  
  339. OSErr DisposeWindowType(WindowPtr wp,WindowType wt){
  340.     short i;
  341.     OSErr err,first_err=noErr;
  342.     WindowPlainUPP close;
  343.     WhatRecordPtr what;
  344.     
  345.     SetPort(wp);
  346.     for (i=1;i<=item_max;i++){
  347.         what=WindowInfo[wt].items[i];
  348.         if (what!=(WhatRecordPtr)0){
  349.             close=(WindowPlainUPP)WhatInfo[TypeToWhat(what->typ)].close;
  350.             if (close!=(WindowPlainUPP)0){
  351.                 err=CallWhatClose(wt,i,close);
  352.                 if (first_err==noErr)
  353.                     first_err=err;
  354.             }
  355.             WindowInfo[wt].items[i]=(WhatRecordPtr)0;
  356.             DisposePtr((Ptr)what);
  357.         }
  358.     }
  359.     
  360.     WindowInfo[wt].window=(DialogPtr)0;
  361.     DisposeDialog(wp);
  362.     return first_err;
  363. }
  364.  
  365. OSErr CloseWindowType(WindowPtr wp,WindowType wt){
  366.     OSErr err,err2;
  367.     Boolean opened=false;
  368.     
  369.     err=ICMapErr(ICBegin(GetInstance(),icReadWritePerm));
  370.     if (err==noErr){
  371.         opened=true;
  372.         err=FlushWindowType(wp,wt);
  373.     }
  374.     
  375.     err2=DisposeWindowType(wp,wt);
  376.     
  377.     if (err==noErr)
  378.         err=err2;
  379.     
  380.     if (opened){
  381.         err2=ICMapErr(ICEnd(GetInstance()));
  382.         if (err==noErr)
  383.             err=err2;
  384.     }
  385.     
  386.     InvalidateAbout();
  387.     
  388.     return err;
  389. }
  390.  
  391. Boolean WindowsEarlyHandleEvent(EventRecord* er){
  392.     WindowPtr wp=FrontWindow();
  393.     
  394.     if (GetWindowType(wp)!=WT_None)
  395.         return WindowEarlyHandleEvent(wp,er);
  396.     return false;
  397. }
  398.  
  399. Boolean WindowsEarlyHandleKey(EventRecord* er){
  400.     WindowPtr wp=FrontWindow();
  401.     
  402.     if (GetWindowType(wp)!=WT_None)
  403.         return WindowEarlyHandleKey(wp,er);
  404.     return false;
  405. }
  406.  
  407. void WindowsDoKey(EventRecord* er){
  408.     WindowPtr wp=FrontWindow();
  409.     
  410.     if (GetWindowType(wp)!=WT_None)
  411.         WindowDoKey(wp,er);
  412. }
  413.  
  414. void WindowsIdle(void){
  415.     WindowType wt;
  416.     
  417.     for (wt=WT_None;wt<=WT_Last;wt++){
  418.         if (WindowInfo[wt].window!=(WindowPtr)0)
  419.             DoWindowIdle(WindowInfo[wt].window);
  420.     }
  421. }
  422.  
  423. void WindowsSetTitle(WindowType wt,const StringPtr title){
  424.     if (WindowInfo[wt].window!=(WindowPtr)0)
  425.         SetWTitle(WindowInfo[wt].window,title);
  426. }
  427.  
  428. void WindowsAdjustMenus(void){
  429.     AdjustTextMenu(GetWindowType(FrontWindow()));
  430. }
  431.  
  432. void WindowsDoEditMenu(short item){
  433.     WindowPtr wp=FrontWindow();
  434.     WindowType wt=GetWindowType(wp);
  435.     
  436.     if (wt!=WT_None)
  437.         DoTextMenu(wt,item);
  438. }
  439.  
  440. short GetWindowID(WindowType wt){
  441.     if (wt==WT_About)
  442.         return 128;
  443.     
  444.     return 200+wt-WT_Main;
  445. }
  446.  
  447. Boolean IsPrefix(StringPtr s,const StringPtr key){
  448.     Str255 ts;
  449.     
  450.     if (IUEqualString(TPCopy(ts,s,1,key[0]),key)==0){
  451.         TPCopy(ts,s,key[0]+1,255);
  452.         SetPString(s,1,ts);
  453.         return true;
  454.     }
  455.     return false;
  456. }
  457.  
  458. OSErr EditCurrentPreference(StringPtr key){
  459.     WindowType wt;
  460.     WhatTemplateArrayHandle what;
  461.     OSErr err=(OSErr)-1;
  462.     short i,id;
  463.     Str255 map;
  464.     
  465.     if (IsPrefix(key,SetPString(map,2,kICMapping,"\p•"))){
  466.         err=WindowsOpen(WT_FileMapping);
  467.         if (err==noErr)
  468.             MappingSetSelection(key);
  469.     } else if (IsPrefix(key,kICHelper)){
  470.         err=WindowsOpen(WT_Helper);
  471.         if (err==noErr)
  472.             HelperSetSelection(key);
  473.     } else {
  474.         for (wt=WT_None;wt<=WT_Last;wt++){
  475.             id=GetWindowID(wt);
  476.             what=(WhatTemplateArrayHandle)GetResource('WHAT',id);
  477.             if (what!=(WhatTemplateArrayHandle)0){
  478.                 HLock((Handle)what);
  479.                 for (i=1;i<=(GetHandleSize((Handle)what)/sizeof(WhatTemplateRecord));i++){
  480.                     if (IUEqualString(key,(*what)[i].key)==0){
  481.                         err=WindowsOpen(wt);
  482.                         if ((*what)[i].typ=='TEXT')
  483.                             SelectTextItem(wt,i);
  484.                     }
  485.                 }
  486.                 HUnlock((Handle)what);
  487.                 ReleaseResource((Handle)what);
  488.             }
  489.         }
  490.     }
  491.     return err;
  492. }
  493.  
  494. OSErr PrepWindow(WindowType wt,short id,WindowPtr wp){
  495.     short i,what;
  496.     OSErr err,first_err=noErr;
  497.     
  498.     SetPort(wp);
  499.     
  500.     WindowInfo[wt].window=wp;
  501.     WindowInfo[wt].id=id;
  502.     WindowInfo[wt].selected_item=-1;
  503.     WindowInfo[wt].window_key_needs_tabs=true;
  504.     first_err=ParseWhat(wt);
  505.     if (first_err==noErr){
  506.         for (i=1;i<=item_max;i++){
  507.             if (WindowInfo[wt].items[i]!=(WhatRecordPtr)0){
  508.                 if (WindowInfo[wt].items[i]->typ=='TEXT')
  509.                     WindowInfo[wt].window_key_needs_tabs=false;
  510.                 what=TypeToWhat(WindowInfo[wt].items[i]->typ);
  511.                 if (((WindowPlainUPP)WhatInfo[what].open)!=(WindowPlainUPP)0){
  512.                     err=CallWhatOpen(wt,i,(WindowPlainUPP)WhatInfo[what].open);
  513.                     if (first_err==noErr)
  514.                         first_err=err;
  515.                 }
  516.             }
  517.         }
  518.     }
  519.     
  520.     if (first_err==noErr)
  521.         if (WindowInfo[wt].selected_item==-1)
  522.             WindowTab(WindowInfo[wt].window,false);
  523.     
  524.     return first_err;
  525. }
  526.  
  527. OSErr ParseWhat(WindowType wt){
  528.     WhatTemplateArrayHandle what;
  529.     short i,max;
  530.     OSErr err=noErr;
  531.     long size;
  532.     
  533.     for (i=1;i<=item_max;i++)
  534.         WindowInfo[wt].items[i]=(WhatRecordPtr)0;
  535.     
  536.     what=(WhatTemplateArrayHandle)GetResource('WHAT',WindowInfo[wt].id);
  537.     if (what!=(WhatTemplateArrayHandle)0){
  538.         HLock((Handle)what);
  539.         
  540.         size=GetHandleSize((Handle)what);
  541.         max=(size)/sizeof(WhatTemplateRecord);
  542.         
  543.         for (i=0;i<max;i++){
  544.             if ((*what)[i].typ!='NULL'){
  545.                 WindowInfo[wt].items[i+1]=(WhatRecordPtr)NewPtr(sizeof(WhatRecord));
  546.                 err=MemError();
  547.                 if (err!=noErr)
  548.                     break;
  549.                 SetPString(WindowInfo[wt].items[i+1]->key,1,(*what)[i].key);
  550.                 WindowInfo[wt].items[i+1]->typ=(*what)[i].typ;
  551.                 WindowInfo[wt].items[i+1]->flags=(*what)[i].flags;
  552.             } else {
  553.                 // must clear the record ptr...
  554.                 WindowInfo[wt].items[i+1]=(WhatRecordPtr)0;
  555.             }
  556.             if (err!=noErr)
  557.                 break; // just in case
  558.         }
  559.         HUnlock((Handle)what);
  560.         ReleaseResource((Handle)what);
  561.     }
  562.     return err;
  563. }
  564.  
  565. OSErr NewICWindow(WindowType wt){
  566.     DialogPtr wp=(DialogPtr)0;
  567.     Point position;
  568.     Rect original_position;
  569.     OSErr err,err2;
  570.     short id=GetWindowID(wt),dlg_id;
  571.     
  572.     err=ICMapErr(ICBegin(GetInstance(),icReadWritePerm));
  573.     if (err==noErr){
  574.         dlg_id=id;
  575.         if ((wt==WT_Font)&&(!System7))
  576.             dlg_id=290;
  577.         wp=GetNewDialog(dlg_id,(Ptr)0,(WindowPtr)-1);
  578.         if (wp==(DialogPtr)0)
  579.             err=memFullErr;
  580.         if (err==noErr)
  581.             err=PrepWindow(wt,id,wp);
  582.         if (err==noErr){
  583.             position=WindowInfo[wt].position;
  584.             if ((position.h!=0)||(position.v!=0)){
  585.                 GetWindowRect(wp,&original_position);
  586.                 MoveWindow(wp,position.h,position.v,false);
  587.                 ShowWindow(wp); // because TitleBarOnScreen required window to be shown
  588.                 if (!TitleBarOnScreen(wp))
  589.                     MoveWindow(wp,original_position.left,original_position.top,false);
  590.             }
  591.             ShowWindow(wp);
  592.         }
  593.         err2=ICMapErr(ICEnd(GetInstance()));
  594.         if (err==noErr)
  595.             err=err2;
  596.     }
  597.     
  598.     // tidy up code
  599.     
  600.     if (err!=noErr)
  601.         if (wp!=(DialogPtr)0)
  602.             DisposeWindowType(wp,wt);
  603.     
  604.     return err;
  605. }
  606.  
  607. OSErr WindowsOpen(WindowType wt){
  608.     OSErr err;
  609.     
  610.     if (WindowInfo[wt].window!=(WindowPtr)0){
  611.         ShowWindow(WindowInfo[wt].window);
  612.         SelectWindow(WindowInfo[wt].window);
  613.         
  614.         return noErr;
  615.     }
  616.     
  617.     /*
  618.         A little glue to spin the cursor when we open a window.  This usually isn't necessary, but
  619.         when opening the font window the building of the font menus can take some time to fill if there
  620.         are a lot of fonts to add to the menu.  This will ensure that the user knows that we are doing
  621.         something and not really hung (which is what I thought the first time I opened the font window
  622.         and had to wait and wait and wait for it to build the menus).
  623.     */
  624.     SpinStart(kForwardDirection);
  625.     
  626.     // also purge & compact memory
  627.     PrepMem();
  628.     
  629.     err=NewICWindow(wt);
  630.     
  631.     InvalidateAbout();
  632.     
  633.     SpinStop();
  634.     
  635.     return err;
  636. }
  637.  
  638. OSErr WindowsClose(WindowPtr wp){
  639.     WindowType wt=GetWindowType(wp);
  640.     
  641.     if (wt!=WT_None)
  642.         return CloseWindowType(wp,wt);
  643.     
  644.     return noErr;
  645. }
  646.  
  647. void WindowsResetPositions(void){
  648.     WindowType wt;
  649.     Point pos;
  650.     
  651.     pos.h=2;
  652.     pos.v=42;
  653.     
  654.     for (wt=WT_Main;wt<WT_Last;wt++){
  655.         WindowInfo[wt-WT_Main].position=pos;
  656.         pos.h+=20*(qd.screenBits.bounds.right>512);
  657.         pos.v+=10*(qd.screenBits.bounds.bottom>=400)+8*(qd.screenBits.bounds.bottom>=480);
  658.     }
  659. }
  660.  
  661. void WindowsRestorePositions(void){
  662.     OSErr err,err2;
  663.     long attr;
  664.     PointArray window_positions=(PointArray)NewPtr(sizeof(Point)*WT_Last);
  665.     long size;
  666.     WindowType wt;
  667.     
  668.     err=ICMapErr(ICBegin(GetInstance(),icReadOnlyPerm));
  669.     if (err==noErr){
  670.         size=sizeof(Point)*WT_Last;
  671.         err=ICMapErr(ICGetPref(GetInstance(),OurWindowPositionKey,&attr,(Ptr)window_positions,&size));
  672.         if ((err==noErr)&&(size!=(sizeof(Point)*WT_Last)))
  673.             err=(OSErr)-1;
  674.         err2=ICMapErr(ICEnd(GetInstance()));
  675.         if (err==noErr)
  676.             err=err2;
  677.     }
  678.     
  679.     if (err==noErr){
  680.         for (wt=WT_Main;wt<WT_Last;wt++)
  681.             WindowInfo[wt].position=window_positions[wt-WT_Main];
  682.     } else
  683.         WindowsResetPositions();
  684.     
  685.     DisposePtr((Ptr)window_positions);
  686. }
  687.  
  688. void WindowsSavePositions(void){
  689.     OSErr err,err2;
  690.     WindowType wt;
  691.     PointArray windows_positions=(PointArray)NewPtr(sizeof(Point)*WT_Last);
  692.     
  693.     for (wt=WT_Main;wt<WT_Last;wt++)
  694.         windows_positions[wt-WT_Main]=WindowInfo[wt].position;
  695.     
  696.     err=ICMapErr(ICBegin(GetInstance(),icReadWritePerm));
  697.     if (err==noErr){
  698.         err=ICMapErr(ICSetPref(GetInstance(),OurWindowPositionKey,ICattr_no_change,(Ptr)windows_positions,(sizeof(Point)*WT_Last)));
  699.         ICMapErr(ICEnd(GetInstance()));
  700.     }
  701.     DisposePtr((Ptr)windows_positions);
  702. }
  703.  
  704. OSErr WindowsFlushAll(void){ // flush all information windows
  705.     WindowType wt;
  706.     OSErr first_err,err;
  707.     
  708.     first_err=ICMapErr(ICBegin(GetInstance(),icReadWritePerm));
  709.     if (first_err==noErr){
  710.         for (wt=WT_Main;wt<=WT_Last;wt++){
  711.             if (WindowInfo[wt].window!=(WindowPtr)0){
  712.                 SetPort(WindowInfo[wt].window);
  713.                 err=FlushWindowType(WindowInfo[wt].window,wt);
  714.                 if (first_err==noErr)
  715.                     first_err=err;
  716.             }
  717.         }
  718.         err=ICMapErr(ICEnd(GetInstance()));
  719.         if (first_err==noErr)
  720.             first_err=err;
  721.     }
  722.     
  723.     return first_err;
  724. }
  725.  
  726. OSErr WindowsCloseAll(void){ // close all information windows
  727.     WindowType wt;
  728.     OSErr err,first_err=noErr;
  729.     
  730.     for (wt=WT_Personal;wt<=WT_Last;wt++){
  731.         if (WindowInfo[wt].window!=(WindowPtr)0){
  732.             err=CloseWindowType(WindowInfo[wt].window,wt);
  733.             if (first_err==noErr)
  734.                 first_err=err;
  735.         }
  736.     }
  737.     
  738.     return first_err;
  739. }
  740.  
  741. void W(short what,OSType xtyp,WindowPlainUPP xopen,WindowEventUPP xkey,WindowEventUPP xclick,
  742.         WindowPlainUPP xidle,WindowPlainUPP xflush,WindowPlainUPP xclose,WindowBooleanUPP xactivate,
  743.         WindowCursorUPP xcursor,short xcursorid){
  744.     WhatInfo[what].typ=xtyp;
  745.     WhatInfo[what].open=xopen;
  746.     WhatInfo[what].key=xkey;
  747.     WhatInfo[what].click=xclick;
  748.     WhatInfo[what].flush=xflush;
  749.     WhatInfo[what].close=xclose;
  750.     WhatInfo[what].activate=xactivate;
  751.     WhatInfo[what].idle=xidle;
  752.     WhatInfo[what].cursor=xcursor;
  753.     WhatInfo[what].cursorid=xcursorid;
  754. }
  755.  
  756. void InitWhats(void){
  757.     WindowPlainUPP np=(WindowPlainUPP)0;
  758.     WindowEventUPP ne=(WindowEventUPP)0;
  759.     WindowBooleanUPP nb=(WindowBooleanUPP)0;
  760.     WindowCursorUPP nc=(WindowCursorUPP)0;
  761.     
  762.     // quick definitions to shorten the function calls
  763. #define NPP NewWindowPlainProc
  764. #define NBP NewWindowBooleanProc
  765. #define NEP NewWindowEventProc
  766. #define NCP NewWindowCursorProc
  767.  
  768.     W(whatNULL,'NULL',np,ne,ne,np,np,np,nb,nc,0);
  769.     
  770.     W(whatTEXT,'TEXT',NPP(WhatOpenText),NEP(WhatKeyText),NEP(WhatClickText),np,NPP(WhatFlushText),NPP(WhatCloseText),
  771.         nb,nc,iBeamCursor);
  772.     
  773.     W(whatSPOP,'SPOP',NPP(WhatOpenPopup),ne,NEP(WhatClickPopup),np,NPP(WhatFlushPopup),NPP(WhatClosePopup),nb,nc,0);
  774.     
  775.     W(whatFFSP,'FFSP',NPP(WhatOpenFSSpec),ne,NEP(WhatClickFSSpec),np,NPP(WhatFlushFSSpec),np,nb,nc,0);
  776.     
  777.     W(whatFPOP,'FPOP',NPP(WhatOpenFont),ne,NEP(WhatClickFont),np,NPP(WhatFlushFont),np,nb,nc,0);
  778.     
  779.     W(whatFMAP,'FMAP',NPP(WhatOpenFileMap),NEP(WhatKeyFileMap),NEP(WhatClickFileMap),np,NPP(WhatFlushFileMap),NPP(WhatCloseFileMap),
  780.         NBP(WhatActivateFileMap),
  781.         NCP(WhatCursorFileMap),
  782.         plusCursor);
  783.     
  784.     W(whatFBUT,'FBUT',np,ne,NEP(WhatClickFileMap),np,np,np,nb,nc,0);
  785.     
  786.     W(whatHMAP,'HMAP',NPP(WhatOpenHelper),NEP(WhatKeyHelper),NEP(WhatClickHelper),np,NPP(WhatFlushHelper),NPP(WhatCloseHelper),
  787.         NBP(WhatActivateHelper),NCP(WhatCursorHelper),plusCursor);
  788.     
  789.     W(whatHBUT,'HBUT',np,ne,NEP(WhatClickHelper),np,np,np,nb,nc,0);
  790.     
  791.     W(whatBUTN,'BUTN',NPP(WhatOpenButton),ne,NEP(WhatClickButton),np,np,np,nb,nc,0);
  792.     
  793.     W(whatFSIZ,'FSIZ',np,ne,NEP(WhatClickFontSize),np,np,np,nb,nc,0);
  794.     
  795.     W(whatCBOX,'CBOX',NPP(WhatOpenCheckBox),ne,NEP(WhatClickCheckBox),np,NPP(WhatFlushCheckBox),np,
  796.         nb,nc,0);
  797. }
  798.  
  799. pascal void AboutBoxUpdate(DialogPtr dlg,short item){
  800.     Rect r;
  801.     Str255 st,ds;
  802.     
  803.     GetDItemRect(dlg,item,&r);
  804.     
  805.     switch (item){
  806.         case 1:
  807.             DrawIcon(128,&r,false);
  808.             break;
  809.         case 3:
  810.             DisplayStyledString(dlg,item,SetPString(st,2,GetAString(st,129,item),app_version.shortVersion));
  811.             break;
  812.         case 8:
  813.             /*
  814.                 DHN- I added this item to the about window to describe the current settings of the application,
  815.                 such as the current version of the installed component, the component in the app that can be
  816.                 installed, and whether the linked-in glue was being used or not.  It will also display the full
  817.                 path to the prefs file in use, even memory availability and other things.  Perhaps even my own
  818.                 styled string may be put in here... ;-)
  819.             */
  820.             {
  821.                 SavedWindowInfo sav;
  822.                 Str255 str,s1;
  823.                 extern long application_version,installed_version;
  824.                 long tot,pur;
  825.                 extern OSErr FSSpecToFullPath(FSSpecPtr fs,StringPtr path);
  826.                 extern FSSpec current_file;
  827.                 FSSpec copy;
  828.                 
  829.                 EnterWindow(dlg,geneva,9,0,&sav);
  830.                 
  831.                 // draw a separator line
  832.                 MoveTo(r.left,r.top+1);
  833.                 LineTo(r.right,r.top+1);
  834.                 
  835.                 MoveTo(r.left+4,r.top+11);
  836.                 SetPString(str,2,"\pApplication Component Version: ",VersionStr(application_version,s1));
  837.                 DrawString(str);
  838.                 
  839.                 MoveTo(r.left+4,r.top+21);
  840.                 SetPString(str,2,"\pInstalled Component Version: ",VersionStr(installed_version,s1));
  841.                 DrawString(str);
  842.                 
  843.                 MoveTo(r.left+4,r.top+31);
  844.                 if (!ICComponentEnabled())
  845.                     SetPString(s1,1,"\pDisabled");
  846.                 else
  847.                     SetPString(s1,1,"\pEnabled");
  848.                 
  849.                 SetPString(str,2,"\pComponent is ",s1);
  850.                 DrawString(str);
  851.                 
  852.                 MoveTo(r.left+4,r.top+41);
  853.                 
  854.                 // make a copy of the fsspec because
  855.                 BlockMoveData((Ptr)(¤t_file),(Ptr)(©),sizeof(FSSpec));
  856.                 // FSSpecToFullPath modifies the spec
  857.                 FSSpecToFullPath(©,s1);
  858.                 SetPString(str,2,"\pPref File: ",s1);
  859.                 
  860.                 // str is the full string, but we need to split it onto two lines...
  861.                 if (StringWidth(str)>(r.right-r.left)-8){
  862.                     // it is greater, try to split into two...
  863.                     unsigned char c=str[0];
  864.                     Boolean done=false;
  865.                     
  866.                     while (!done){
  867.                         while ((str[c]!=' ')&&(str[c]!='-')&&(str[c]!=':'))
  868.                             c--;
  869.                         
  870.                         TPCopy(s1,str,1,c);
  871.                         
  872.                         done=(StringWidth(s1)<=((r.right-r.left)-8));
  873.                         if (!done)
  874.                             c--;
  875.                     }
  876.                     
  877.                     // chars 1 through c are now stored in s1, and s1 can be printed
  878.                     DrawString(s1);
  879.                     
  880.                     MoveTo(r.left+8,r.top+51);
  881.                     // chars 1 through c should be deleted from str, then it can be printed
  882.                     DrawString(Delete(str,1,c));
  883.                 } else {
  884.                     // finish off with the last piece...
  885.                     DrawString(str);
  886.                 }
  887.                 
  888.                 r.left+=4;
  889.                 r.top+=53;
  890.                 EraseRect(&r);
  891.                 
  892.                 MoveTo(r.left,r.top+8);
  893.                 PurgeSpace(&tot,&pur);
  894.                 tot/=1024;
  895.                 SetPString(str,3,"\pApproximately ",DecStr(tot,s1),"\p KB available");
  896.                 DrawString(str);
  897.                 
  898.                 ExitWindow(&sav);
  899.             }
  900.             break;
  901.         default:
  902.             DisplayStyledString(dlg,item,GetAString(st,129,item));
  903.             break;
  904.     }
  905. }
  906.  
  907. UserItemUPP __gAboutBoxUpdate;
  908.  
  909. OSErr InitICWindows(void){
  910.     WindowType wt;
  911.     short i,kind;
  912.     WindowPtr wp;
  913.     OSErr err;
  914.     
  915.     InitICWindowGlobals();
  916.     InitWhats();
  917.     
  918.     // Initialize the spinning cursor library
  919.     err=SpinInit();
  920.     
  921.     for (wt=WT_None;wt<=WT_Last;wt++){
  922.         WindowInfo[wt].window=(DialogPtr)0;
  923.         WindowInfo[wt].window_key_needs_tabs=false;
  924.         WindowInfo[wt].position.h=WindowInfo[wt].position.v=0;
  925.     }
  926.     
  927.     WindowsResetPositions();
  928.     
  929.     // bring the about box up hidden and leave it there
  930.     
  931.     err=noErr;
  932.     wp=GetNewDialog(128,(Ptr)0,(WindowPtr)-1);
  933.     WindowInfo[WT_About].window=wp;
  934.     if (wp==(WindowPtr)0)
  935.         err=memFullErr;
  936.     
  937.     if (err==noErr)
  938.         err=PrepWindow(WT_About,128,wp);
  939.     
  940.     if (err==noErr){
  941.         short cnt=CountDItems(wp);
  942.         __gAboutBoxUpdate=NewUserItemProc(AboutBoxUpdate);
  943.         
  944.         for (i=1;i<=cnt;i++){
  945.             GetDItemKind(wp,i,&kind);
  946.             
  947.             if ((kind&0x007f)==userItem)
  948.                 SetDItemHandle(wp,i,(Handle)__gAboutBoxUpdate);
  949.         }
  950.     }
  951.     
  952.     return err;
  953. }
  954.  
  955.